import os

from .app import Flask, override_json_encoder

from .celery import celery_app
from app.libs.sentry_utils import before_send


def register_blueprint(_app):
    from .api.v2 import create_blueprint_v2
    from .api.v3 import create_blueprint_v3
    _app.register_blueprint(create_blueprint_v2(), url_prefix='/api/v2')
    _app.register_blueprint(create_blueprint_v3(), url_prefix='/api/v3')


def register_plugin(_app):
    import sentry_sdk
    from sentry_sdk.integrations.flask import FlaskIntegration
    from app.errors import OMSAPIException, OMSAPINotOk

    if SENTRY_DSN := _app.config.get('SENTRY_DSN'):
        sentry_sdk.init(
            dsn=SENTRY_DSN,
            integrations=[FlaskIntegration()],
            environment=os.environ.get('FLASK_ENV', "development"),
            ignore_errors=[OMSAPIException, OMSAPINotOk],
            before_send=before_send,
            traces_sample_rate=1.0,
            release="2.0.0"
        )
    from app.log import set_logger
    set_logger(_app)

    from flask_cors import CORS
    CORS(_app, supports_credentials=True)

    # from app.db import mongo
    # mongo.init_app(_app)

    from app.db import redis
    redis.init_app(_app)

    from app.db import db
    db.init_app(_app)

    from app.auth import jwt
    jwt.init_app(_app)
    celery_conf = {
        'broker_url': _app.config['BROKER_URL'],
        'result_backend': _app.config['CELERY_RESULT_BACKEND'],
        'ONCE': {
            'backend': 'celery_once.backends.Redis',
            'settings': {
                'url': _app.config['CELERY_ONCE_URL'],
                'default_timeout': _app.config['CELERY_ONCE_TIMEOUT']
            }
        }
    }
    celery_app.conf.update(celery_conf)

    from app.cache import cache
    cache.init_app(_app)


def register_app_func(_app):
    from app.auth import refresh_expiring_jwts, g_context
    _app.before_request_funcs.setdefault(None, []).extend([g_context])
    # Remove refresh jwt
    # _app.after_request_funcs.setdefault(None, []).extend([refresh_expiring_jwts])

    from app.errors import framework_404, framework_500
    _app.register_error_handler(404, framework_404)
    _app.register_error_handler(500, framework_500)


def create_app():
    _app = Flask(__name__)
    _app.config.from_object('app.config.settings')
    register_blueprint(_app)
    register_plugin(_app)
    register_app_func(_app)
    override_json_encoder(_app)
    return _app
